# coding: utf-8
# @Author: cyl
import ujson
import requests
import warnings
from typing import Any
from requests import Response
from utils.logger_handle import logger
from utils.base_utils import dictToUriStr
from setting import (
    PrefixUrl
)

requests.packages.urllib3.disable_warnings()
warnings.filterwarnings('ignore')


# noinspection DuplicatedCode
class RequestHandle:
    """requests请求封装"""

    @staticmethod
    def required(method: str, url: str, data=None, headers=None) -> Response:
        """application为表单格式"""
        match method:
            case "get":
                res = requests.get(url=url, params=data, headers=headers, verify=False)
            case "post":
                res = requests.post(url=url, data=data, headers=headers, verify=False)
            case "put":
                res = requests.put(url=url, data=data, headers=headers, verify=False)
            case "delete":
                res = requests.delete(url=url, params=data, headers=headers, verify=False)
            case "patch":
                res = requests.patch(url=url, data=data, headers=headers, verify=False)
            case _:
                raise ValueError(f"Unsupported method: {method}")
        return res

    @staticmethod
    def required_json(method: str, url: str, data=None, json=None, headers=None) -> Response:
        """application为json格式"""
        match method:
            case "get":
                res = requests.get(url=url, params=data, verify=False)
            case "post":
                res = requests.post(url=url, json=json, headers=headers, verify=False)
            case "put":
                res = requests.put(url=url, data=data, headers=headers, verify=False)
            case "delete":
                res = requests.delete(url=url, params=data, headers=headers, verify=False)
            case "patch":
                res = requests.patch(url=url, json=json, headers=headers, verify=False)
        return res

    @staticmethod
    def visited(method: str, url: str, **kwargs) -> Response:
        return requests.request(method=method.upper(), url=url, verify=False, **kwargs)

    def currency_request(
            self,
            _module: str,
            method: str,
            point: str,
            content_type: str = "application/json;charset=UTF-8",
            resful: bool = True,
            **kwargs
    ) -> dict | Response:
        """
        通用请求
        :param _module: request module
            dougong: 斗拱客户端
            project_b: ...
            project_c: ...
        :param method: request method
        :param point: request uri
        :param content_type: headers type
        :param resful: 是否序列化输出
        """
        if method not in self.methods:
            raise Exception("request method is not allowed!")
        headers: dict = {
            "Content-Type": content_type,
            "Connection": "Keep-Alive",
            "Accept-Encoding": "gzip,deflate",
            "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36"
        }
        match _module:
            case "dougong":
                is_exists: bool = self.pickledb.exists("DouGongLoginJwtToken")
                if is_exists:
                    jwt_token: str = self.pickledb.get("DouGongLoginJwtToken")
                    headers["Authorization"] = "Bearer " + jwt_token
                _url: str = PrefixUrl + point
            case "project_b":
                headers["access-token"] = self.db.get("ClientBToken")
                _url: str = self.db.get("ccid_context") + point
            case "project_c":
                headers["access-token"] = self.db.get("ClientCToken")
                _url: str = self.db.get("ccid_data_context") + point
            case _:
                raise Exception("request module to be implemented!")
        params: dict = kwargs.get("params", {})
        logger.info("{}, {}".format(method, point + dictToUriStr(params)))

        res = self.visited(method, _url, headers=headers, **kwargs)
        assert res.status_code in (200, 204, 500, 400)
        if resful:
            return ujson.loads(str(res.content, encoding="utf-8"))
        return res

    def dou_request(
            self,
            method: str,
            point: str,
            resJson: bool = True,
            **kwargs
    ) -> Any | Response:
        """斗拱客户端"""
        return self.currency_request(
            _module="dougong",
            method=method,
            point=point,
            resful=resJson,
            **kwargs
        )
